<template>
  <a-row class="map-input">
    <a-col :span="24">
      <a-auto-complete
        :placeholder="
          props.placeholder ? props.placeholder : `请填写该职位的工作地点`
        "
        allowClear
        @search="onSearch"
        @select="onSelect"
        v-model:value="inputValue.address"
        size="large"
        :options="poiResult"
      >
      </a-auto-complete>
    </a-col>

    <a-col :span="24" class="mt-16">
      <div class="map" ref="mapRef" />
    </a-col>
  </a-row>
</template>
<script lang="ts" setup>
import { ref, onMounted, onUnmounted, computed, watch } from 'vue';
import _ from 'lodash';
import { Poi, AddressType } from './types';

type Props = {
  value: AddressType;
  placeholder?: string;
  detailAddress: string;
  city?: string;
};

const props = defineProps<Props>();

const $emit = defineEmits(['change', 'update:value', 'update:detailAddress']);

const mapRef = ref();
const poiResult = ref<Poi[]>([]);

const inputValue = computed<AddressType>({
  get() {
    return props.value;
  },
  set(address) {
    $emit('update:value', { address, ...location });
  },
});

// const detailAddress2 = computed<string>({
//   get() {
//     return props.detailAddress;
//   },
//   set(value) {
//     $emit('update:detailAddress', value);
//   },
// });

let mapIns: any;
let poiSuggestion: any;
let mapMarkerLayer: any;
let mapGeoCoder: any;
let location: any = {};

onMounted(() => {
  init();
});

onUnmounted(() => {
  if (mapIns) {
    mapIns.destroy();
  }
});

watch(
  props.value,
  () => {
    const TMap = window.TMap;
    const lat = props.value?.lat > 0 ? props.value.lat : 39.984104;
    const lng = props.value?.lng > 0 ? props.value.lng : 116.307503;
    const center = new TMap.LatLng(lat, lng); //设置中心点坐标
    mapMarkerLayer.setGeometries([
      { id: +new Date(), styleId: 'myStyle', position: center },
    ]);
    // if (mapIns) {
    //   mapIns.setCenter(center);
    // }
  },
  {
    deep: true,
  },
);

async function init() {
  const TMap = window.TMap;

  // const b = await new TMap.service.IPLocation();

  const lat = props.value?.lat > 0 ? props.value.lat : 42.257429;
  const lng = props.value?.lng > 0 ? props.value.lng : 118.901766;

  const center = new TMap.LatLng(lat, lng); //设置中心点坐标

  // 如果输入了地址，则在地图上标记输入的位置
  const geometries = props.value.address
    ? [
        {
          id: +new Date(),
          styleId: 'myStyle',
          position: center,
        },
      ]
    : [];

  mapIns = new TMap.Map(mapRef.value, {
    center: center,
    viewMode: '2D',
    showControl: false,
  });

  poiSuggestion = new TMap.service.Suggestion({
    region: props.city || '', //  城市限制
  });

  mapGeoCoder = new TMap.service.Geocoder();

  mapMarkerLayer = new TMap.MultiMarker({
    map: mapIns, //指定地图容器
    //样式定义
    styles: {
      // 创建一个styleId为"myStyle"的样式（styles的子属性名即为styleId）
      myStyle: new TMap.MarkerStyle({
        width: 25, // 点标记样式宽度（像素）
        height: 35, // 点标记样式高度（像素）
        src: 'https://mapapi.qq.com/web/lbs/javascriptGL/demo/img/markerDefault.png', // 图片路径
        // 焦点在图片中的像素位置，一般大头针类似形式的图片以针尖位置做为焦点，圆形点以圆心位置为焦点
        anchor: { x: 16, y: 32 },
      }),
    },
    //点标记数据数组
    geometries,
  });

  // 监听点击事件添加marker
  mapIns.on('click', onMapClick);
}

const onSearch = _.debounce((keyword: any) => {
  if (poiSuggestion) {
    if (_.isEmpty(keyword)) {
      return;
    }
    poiSuggestion
      .getSuggestions({ keyword })
      .then((resp: any) => {
        if (resp.status === 0) {
          resp.data.forEach((t: any) => {
            t.label = t.address + t.title;
            t.value = t.label;
          });
          poiResult.value = resp.data;
          if (resp.data.length) {
            const first = resp.data[0];
            const result = { address: keyword, ...first.location };
            $emit('change', result);
            $emit('update:value', result);
          } else {
            // 清空输入项
          }
        }
      })
      .catch((err: any) => {
        console.log(err);
      });
  }
}, 300);

const onMapClick = _.debounce((evt: any) => {
  const TMap = window.TMap;
  mapGeoCoder
    .getAddress({
      location: evt.latLng,
    })
    .then((resp: any) => {
      if (resp.status === 0) {
        const _location = resp.result.location;
        const _address = resp.result.address;
        const city = resp.result?.ad_info?.city;
        location = { ..._location, city };
        inputValue.value = _address;

        mapMarkerLayer.setGeometries([]);
        const position = new TMap.LatLng(location.lat, location.lng);
        mapMarkerLayer.add([{ id: +new Date(), styleId: 'myStyle', position }]);

        const result = { address: _address, ...location };

        $emit('change', result);
        $emit('update:value', {
          address: _address,
          ...location,
        });
      }
    });
}, 300);

function onSelect(v: any) {
  const item = poiResult.value.find(t => t.label === v);

  if (item) {
    const TMap = window.TMap;
    mapMarkerLayer.setGeometries([]);
    const position = new TMap.LatLng(item.location.lat, item.location.lng);
    location = { ...position, city: item?.city };
    mapIns.setCenter(position);
    mapMarkerLayer.add([{ id: item.id, styleId: 'myStyle', position }]);

    $emit('change', {
      address: v,
      ...location,
    });
    $emit('update:value', {
      address: v,
      ...location,
    });
  }
}
</script>

<style lang="less" scoped>
.map-input {
  .mt-16 {
    margin-top: 16px;
  }
  :deep(.ant-col-24) {
    max-width: 94.5%;
  }
  .map {
    height: 300px;
    width: 100%;
  }
}
</style>
